﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Management.Instrumentation;
using System.IO;

namespace Tzync
{
    public class Utility
    {
        //Description     : Function to get the CPUID                    
        public static String GetCPUId()
        {
            try
            {
            
            String driveLetter = "";
            SelectQuery query = new SelectQuery( "select name from win32_logicaldisk where drivetype=3");
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
            foreach (ManagementObject mo in searcher.Get())
            {
                driveLetter = mo["name"].ToString().TrimEnd(':');
                break;
            }
            ManagementObject dsk = new ManagementObject(@"win32_logicaldisk.deviceid=""" + driveLetter + @":""");
            dsk.Get();

            string volumeSerial = dsk["VolumeSerialNumber"].ToString();
            return volumeSerial;
            }catch(Exception)
            {
                throw;
            }                               

        }

        public static String GetMotherBoardId()
        {
            String motherBoardID = "";
            ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT Product FROM Win32_BaseBoard");
            // Executing the query...
            // Because the machine has a single Motherborad, then a single object (row) returned.


            ManagementObjectCollection information = searcher.Get();
            foreach (ManagementObject obj in information)
            {
                // Retrieving the properties (columns)    
                // Writing column name then its value    
                foreach (PropertyData data in obj.Properties)
                    motherBoardID = data.Value.ToString();
            }
            // For typical use of disposable objects enclose it in a using statement instead.
            searcher.Dispose();
            return motherBoardID;
        }

        //Description     : Function to calculate the size of a directory
        //Pre-Conditions  : directory is not NULL
        //Post-Conditions : size of the directory is calculated.

        public static long CalculateDirectorySize(DirectoryInfo directory)
        {
            long totalSize = 0;

            // Examine all contained files.
            FileInfo[] files = directory.GetFiles();
            foreach (FileInfo file in files)
            {
                totalSize += file.Length;
            }

            DirectoryInfo[] dirs = directory.GetDirectories();
            foreach (DirectoryInfo dir in dirs)
            {
                totalSize += CalculateDirectorySize(dir);
            }

            return totalSize;
        }

        //Return : int (index)
        //index>=0, if present
        //index<0, if not found
        //Input sorted list of string. StartVal is an optional guess value - default is 0.

        public static int binarySearch(string a, List<String> b, int startVal)
        {

            int listLength = b.Count;
            if (listLength == 0 || startVal > listLength) return -1;

            int lowerBound = 0, upperBound = listLength - 1, moreIndex = -1;
            // Find match in larger folder using binary search

            while (lowerBound <= upperBound)
            {
                if (moreIndex == -1)
                    moreIndex = startVal; // setting initial value proportionally so search space is (hopefully) reduced.
                else
                    moreIndex = (int)(lowerBound + upperBound) / 2; //Binary search updating index.              

                switch (a.CompareTo(b.ElementAt(moreIndex)))
                {
                    case 0: // Filename match!
                        return moreIndex;
                    case 1: //greater
                        lowerBound = moreIndex + 1;
                        break;
                    case -1: //lesser
                        upperBound = moreIndex - 1;
                        break;
                }
            }

            return -1; //No match. It is a difference.                             
        }

        public static int binarySearch(string a, List<String> b)
        {
            return binarySearch(a, b, 0);
        }

        public static string GetMD5Hash(string input)
        {
            System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] bs = System.Text.Encoding.UTF8.GetBytes(input);
            bs = x.ComputeHash(bs);
            System.Text.StringBuilder s = new System.Text.StringBuilder();
            foreach (byte b in bs)
            {
                s.Append(b.ToString("x2").ToLower());
            }
            string password = s.ToString();
            return password;
        }
    }
}
